#ifndef RECTANGLECUH
#define RECTANGLECUH
#include"material.cuh"
#include"hitable_list.cuh"
//矩形 片面 厚度0.0002
class xy_rect: public hitable {
public:
    __duel__ xy_rect() {}
    __duel__ ~xy_rect() 
    {
        //printf("call~xy_rect() k=%f \n",k);
        THISNULL(mp);
        //printf("call~xy_rect()done\n");
    }
    __duel__ xy_rect(float _x0, float _x1, float _y0, float _y1, float _k, material* mat)
        : x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat) {};

    __device__ virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;

    __duel__ virtual bool bounding_box(float t0, float t1, aabb& output_box)const
    {
        output_box =  aabb(vec3(x0,y0, k-0.0001), vec3(x1, y1, k+0.0001));
        return true;
    }

public:
    material* mp;
    float x0, x1, y0, y1, k;
};
class xz_rect: public hitable {
public:
    __duel__ xz_rect() {}
    __duel__ ~xz_rect() 
    {
        //printf("call~xz_rect() k=%f \n",k);
        THISNULL(mp);
        //printf("call~xz_rect()done\n");
    }
    __duel__ xz_rect(float _x0, float _x1, float _z0, float _z1, float _k, material* mat)
        : x0(_x0), x1(_x1), z0(_z0), z1(_z1), k(_k), mp(mat) {};

    __device__ virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;

    __duel__ virtual bool bounding_box(float t0, float t1, aabb& output_box)const
    {
        output_box =  aabb(vec3(x0,k-0.0001,z0 ), vec3(x1, k+0.0001, z1));
        return true;
    }

public:
    material* mp;
    float x0, x1, z0, z1, k;
};
class yz_rect: public hitable {
public:
    __duel__ yz_rect() {}
    __duel__ ~yz_rect() 
    {
        //printf("call~yz_rect() k=%f \n",k);
        THISNULL(mp);
        //printf("call~yz_rect()done\n");
    }
    __duel__ yz_rect(float _y0, float _y1, float _z0, float _z1, float _k, material* mat)
        : y0(_y0), y1(_y1), z0(_z0), z1(_z1), k(_k), mp(mat) {};

    __device__ virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;

    __duel__ virtual bool bounding_box(float t0, float t1, aabb& output_box)const
    {
        output_box =  aabb(vec3(k-0.0001,y0,z0 ), vec3(k+0.0001,y1,z1));
        return true;
    }

public:
    material* mp;
    float y0, y1, z0, z1, k;
};
//长方体
class box:public hitable
{
public:
    __duel__ box(){};
    __duel__ box(const vec3 p0, const vec3 p1, material* ptr);
    __duel__ ~box();
    __device__ virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;

    __duel__ virtual bool bounding_box(float t0, float t1, aabb& output_box)const
    {   
        output_box = aabb(box_min, box_max);
        return true;
    }

public:
    vec3 box_min;
    vec3 box_max;
    hitable_list sides;
    hitable **hit_list;
};
__duel__ box::~box()
{
    //简单置为null
    for(int i=1;i<6;i++)
    {
        ((xy_rect*)(hit_list[i]))->mp=nullptr;   
    }
    for(int i=0;i<6;i++)
    {
        THISNULL(hit_list[i]);   
    }
    printf("call~box()done");
    THISNULL(hit_list);
}
__duel__ box::box(const vec3 p0, const vec3 p1, material* ptr)
{
    box_min=p0;
    box_max=p1;
    hit_list=new hitable*[6];
    hit_list[0]=new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr);
    hit_list[1]=new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr);

    hit_list[2]=new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr);
    hit_list[3]=new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr);

    hit_list[4]=new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr);
    hit_list[5]=new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr);
    sides.list=hit_list;
    sides.list_size=6;

}
__device__  bool box::hit(const ray& r, float t_min, float t_max, hit_record& rec) const
{//
    return sides.hit(r,t_min,t_max,rec);
}








__device__ bool yz_rect::hit(const ray& r, float t_min, float t_max, hit_record& rec) const
{
    auto t= (k-r.origin().x())/r.direction().x();
    if(t<t_min||t>t_max)
    {//光线非法，超出范围
        return false;
    }
    auto y = r.origin().y() + t*r.direction().y();
    auto z = r.origin().z() + t*r.direction().z();
    if (y < y0 || y > y1 || z < z0 || z > z1)
    {//交点不在矩形片面上
        return false;
    }
    rec.u = (y-y0)/(y1-y0);
    rec.v = (z-z0)/(z1-z0);
    rec.t = t;
    vec3 outward_normal = vec3(1, 0, 0);
    //将片面法线置为光线可（反射，折射，漫反射等等）
    //漫反射我们规定只有一面是合法的
    rec.set_face_normal(r, outward_normal);
    rec.mat_ptr = mp;
    rec.p = r.point_at_parameter(t);
    return true;
}
__device__ bool xz_rect::hit(const ray& r, float t_min, float t_max, hit_record& rec) const
{
    auto t= (k-r.origin().y())/r.direction().y();
    if(t<t_min||t>t_max)
    {//光线非法，超出范围
        return false;
    }
    auto x = r.origin().x() + t*r.direction().x();
    auto z = r.origin().z() + t*r.direction().z();
    if (x < x0 || x > x1 || z < z0 || z > z1)
    {//交点不在矩形片面上
        return false;
    }
    rec.u = (x-x0)/(x1-x0);
    rec.v = (z-z0)/(z1-z0);
    rec.t = t;
    vec3 outward_normal = vec3(0, 1, 0);
    //将片面法线置为光线可（反射，折射，漫反射等等）
    //漫反射我们规定只有一面是合法的
    rec.set_face_normal(r, outward_normal);
    rec.mat_ptr = mp;
    rec.p = r.point_at_parameter(t);
    return true;
}
__device__ bool xy_rect::hit(const ray& r, float t_min, float t_max, hit_record& rec) const
{
    auto t= (k-r.origin().z())/r.direction().z();
    if(t<t_min||t>t_max)
    {//光线非法，超出范围
        return false;
    }
    auto x = r.origin().x() + t*r.direction().x();
    auto y = r.origin().y() + t*r.direction().y();
    if (x < x0 || x > x1 || y < y0 || y > y1)
    {//交点不在矩形片面上
        return false;
    }
    rec.u = (x-x0)/(x1-x0);
    rec.v = (y-y0)/(y1-y0);
    rec.t = t;
    vec3 outward_normal = vec3(0, 0, 1);
    //将片面法线置为光线可（反射，折射，漫反射等等）
    //漫反射我们规定只有一面是合法的
    rec.set_face_normal(r, outward_normal);
    rec.mat_ptr = mp;
    rec.p = r.point_at_parameter(t);
    return true;
}











#endif